package com.unis.controller.system;

import com.alibaba.fastjson.JSON;
import com.unis.common.exception.app.UploadFailureException;
import com.unis.common.secure.authc.UserInfo;
import com.unis.common.util.CreateImgUtil;
import com.unis.common.util.TimeUtil;
import com.unis.common.util.ValidateUtil;
import com.unis.controller.BaseController;
import com.unis.model.system.DwDzz;
import com.unis.pojo.Attachment;
import com.unis.pojo.CxFlwsJtl;
import com.unis.pojo.ZfflwsJtl;
import com.unis.service.system.AttachmentService;
import com.unis.service.system.CodeService;
import com.unis.service.system.DwDzzService;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2019/1/30/030.
 */
@Controller
@RequestMapping("/attachment")
public class FileUploadController extends BaseController {
    private static final Logger logger = LoggerFactory.getLogger(FileUploadController.class);
    @Autowired
    private AttachmentService attachmentService;
    @Autowired
    private DwDzzService dwDzzService;
    @Autowired
    private CodeService codeService;

    /**
     * 上传并返回mongo的Pk(带有存储路径)
     *
     * @param request
     * @return
     * @throws IOException
     */
    @RequiresPermissions(value = {"ROLE_CURD", "ROLE_XTGL"}, logical = Logical.OR)
    @RequestMapping("/upload")
    @ResponseBody
    public Map<String, String> fileUpload(MultipartHttpServletRequest request) {
        Map<String, String> map = new HashMap<>();
        if (request != null && request.getFileNames() != null) {
            Iterator<String> iterator = request.getFileNames();
            while (iterator.hasNext()) {
                String fileDomName = iterator.next();
                List<MultipartFile> files = request.getFiles(fileDomName);

                if (files != null) {
                    for (MultipartFile file : files) {

                        Attachment attachment = new Attachment();
                        try {
                            attachment.setContent(file.getBytes());
                        } catch (IOException e) {
                            logger.error("attachment/upload file to bytes is error.\n" + e);
                            throw new UploadFailureException("attachment/upload file to bytes is error.");
                        }
                        attachment.setPk(new ObjectId().toString());
                        attachment.setFilename(file.getOriginalFilename());
                        attachment.setContentType(file.getContentType());

                        attachment.setAttachmentDb(request.getParameter("eff"));

                        try {
                            attachment = attachmentService.upload(attachment);
                        } catch (IOException e) {
                            logger.error("attachment/upload upload to mongo is error.\n" + e);
                            throw new UploadFailureException("attachment/upload upload to mongo is error.");
                        }
                        String mongoPk = attachment.getAttachmentDb() + "/" + attachment.getCatalog() + "/" + attachment.getPk();
                        map.put(fileDomName + "_mongo", mongoPk);
                    }
                }
            }
        }
        map.put("succ", "success");
        return map;
    }

    /**
     * 上传并返回使用":"拼接的mongo.pk(带有路径):文件名称:文件类型
     *
     * @param request
     * @return
     * @throws IOException
     */
    @RequestMapping("/uploadR")
    @ResponseBody
    public Map<String, String> fileUploadRespName(MultipartHttpServletRequest request) {
        Map<String, String> map = new HashMap<>();
        if (request != null && request.getFileNames() != null) {
            Iterator<String> iterator = request.getFileNames();
            while (iterator.hasNext()) {
                String fileDomName = iterator.next();
                List<MultipartFile> files = request.getFiles(fileDomName);

                if (files != null) {
                    for (MultipartFile file : files) {

                        Attachment attachment = new Attachment();
                        try {
                            attachment.setContent(file.getBytes());
                        } catch (IOException e) {
                            logger.error("attachment/uploadR file to bytes is error.\n" + e);
                            throw new UploadFailureException("attachment/uploadR file to bytes is error.");
                        }
                        attachment.setPk(new ObjectId().toString());
                        attachment.setFilename(file.getOriginalFilename());
                        attachment.setContentType(file.getContentType());

                        attachment.setAttachmentDb(request.getParameter("eff"));

                        try {
                            attachment = attachmentService.upload(attachment);
                        } catch (IOException e) {
                            logger.error("attachment/uploadR upload to mongo is error.\n" + e);
                            throw new UploadFailureException("attachment/uploadR upload to mongo is error.");
                        }
                        String mongoPk = attachment.getAttachmentDb() + "/" + attachment.getCatalog() + "/" + attachment.getPk() + ":" + attachment.getFilename() + ":" + attachment.getContentType();
                        map.put(fileDomName + "_mongo", mongoPk);
                    }
                }
            }
        }
        map.put("succ", "success");
        return map;
    }

    /**
     * 根据mongo.pk(带有路径)获取附件
     *
     * @param response
     * @param pk
     */
    @RequestMapping("/download")
    public void download(HttpServletResponse response, String pk) {
        if (StringUtils.isNotBlank(pk)) {
            String[] mongo = pk.split("/");
            if (mongo != null && mongo.length > 0) {
                Attachment attachment = new Attachment();
                if (mongo.length == 3) {
                    attachment.setAttachmentDb(mongo[0]);
                    attachment.setCatalog(mongo[1]);
                    attachment.setPk(mongo[2]);
                } else if (mongo.length == 1) {
                    attachment.setCatalog("public");
                    attachment.setPk(pk);
                }

                attachment = attachmentService.download(attachment);

                if (attachment != null) {
                    ServletOutputStream out = null;
                    try {
                        //设置文件下载头
                        if (StringUtils.isNotBlank(attachment.getFilename())) {
                            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(attachment.getFilename(), "UTF-8"));
                        }
                        //1.设置文件ContentType类型，这样设置，会自动判断下载文件类型
                        response.setContentType("multipart/form-data");

                        out = response.getOutputStream();
                        out.write(attachment.getContent());
                        out.flush();
                        out.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                        logger.error("attachment download write to out is error.");
                    }
                }
            }
        }
    }

    @RequiresPermissions("ROLE_ZF")
    @RequestMapping("/zfws")
    public void createZfws(HttpServletResponse response, ZfflwsJtl zfws) {
        if (zfws != null) {
            try {
                zfws.setZzsj(TimeUtil.strToDate(zfws.getZzsj_(), "yyyyMMddHHmmss"));
            } catch (ParseException e) {
                logger.error("valid createZfws ZfflwsJtl is error:转账时间格式有误");
                return;
            }

            UserInfo user = attachmentService.getUserInfo();

            DwDzz dzz = null;
            try {
                dzz = dwDzzService.queryDwDzzByDwdm(user.getJgdm());
            } catch (Exception e) {
                logger.error("createZfws get DwDzz is error :" + e.getMessage());
                return;
            }

            if (dzz != null) {
                //设置参数
                zfws.setDwmc(dzz.getDwmc());
                try {
                    Map<String, Map<String, String>> dicMap = codeService.queryDicWithSpecCode("010107", "010104");
                    zfws.setAjlb(dicMap.get("010107").get(zfws.getAjlb()));
                    String zzfs_ = dicMap.get("010104").get(zfws.getZzfs());
                    if (zzfs_ != null && StringUtils.isNotBlank(zzfs_)) {
                        zfws.setZzfs(zzfs_);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error("createZfws is error :字典获取异常");
                    return;
                }
                System.out.println(JSON.toJSONString(zfws));

                String[] mongo = dzz.getZfz().split("/");

                Attachment attachment = new Attachment();
                attachment.setAttachmentDb(mongo[0]);
                attachment.setCatalog(mongo[1]);
                attachment.setPk(mongo[2]);
                attachment = attachmentService.download(attachment);
                if (attachment != null) {
                    zfws.setZfz(attachment.getContent());
                }
            }
            String msg = ValidateUtil.valid(zfws);
            if (StringUtils.isNotBlank(msg)) {
                logger.error("valid createZfws ZfflwsJtl is error :" + msg);
            } else {
                byte[] b = null;
                try {
                    b = CreateImgUtil.createZfFlwsImg(zfws);
                } catch (IOException e) {
                    e.printStackTrace();
                    logger.error("createZfws generate img is error.\n" + e.getMessage());
                    throw new UploadFailureException("createZfws generate img is error.");
                }
                if (b != null && b.length > 0) {
                    ServletOutputStream out = null;
                    //设置文件下载头
                    try {
                        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(System.currentTimeMillis() + ".jpg", "UTF-8"));
                        //1.设置文件ContentType类型，这样设置，会自动判断下载文件类型
                        response.setContentType("multipart/form-data");

                        out = response.getOutputStream();
                        out.write(b);
                        out.flush();
                        out.close();
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                        logger.error("createZfws get file name is error.");
                    } catch (IOException e) {
                        e.printStackTrace();
                        logger.error("createZfws write to out is error.");
                    }
                }
            }
        } else {
            logger.error("createZfws zfws is null error.");
        }
    }

    @RequiresPermissions("ROLE_CX")
    @RequestMapping("/cxws")
    public void createCxws(HttpServletResponse response, CxFlwsJtl cxws) {
        if (cxws != null) {
            DwDzz dzz = null;
            try {
                UserInfo user = attachmentService.getUserInfo();
                dzz = dwDzzService.queryDwDzzByDwdm(user.getJgdm());
            } catch (Exception e) {
                logger.error("createZfws get DwDzz is error :" + e.getMessage());
                return;
            }
            if (dzz != null) {
                cxws.setDwmc(dzz.getDwmc());
                cxws.setDwjc(dzz.getDwjc());
                cxws.setDzyear(dzz.getDzyear());
                cxws.setDzz(dzz.getDzz() + "");

                String[] mongo = dzz.getCxz().split("/");

                Attachment attachment = new Attachment();
                attachment.setAttachmentDb(mongo[0]);
                attachment.setCatalog(mongo[1]);
                attachment.setPk(mongo[2]);
                attachment = attachmentService.download(attachment);
                if (attachment != null) {
                    cxws.setCxz(attachment.getContent());
                }
            }
            String msg = ValidateUtil.valid(cxws);
            if (StringUtils.isNotBlank(msg)) {
                logger.error("valid createCxws CxFlwsJtl is error :" + msg);
            } else {
                byte[] b = null;
                try {
                    b = CreateImgUtil.createCxFlwsImg(cxws);
                } catch (IOException e) {
                    logger.error("createCxws generate img is error.\n" + e.getMessage());
                    throw new UploadFailureException("createCxws generate img is error.");
                }
                if (b != null && b.length > 0) {
                    ServletOutputStream out = null;
                    //设置文件下载头
                    try {
                        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(System.currentTimeMillis() + ".jpg", "UTF-8"));
                        //1.设置文件ContentType类型，这样设置，会自动判断下载文件类型
                        response.setContentType("multipart/form-data");

                        out = response.getOutputStream();
                        out.write(b);
                        out.flush();
                        out.close();
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                        logger.error("createCxws get file name is error.");
                    } catch (IOException e) {
                        e.printStackTrace();
                        logger.error("createCxws write to out is error.");
                    }
                }
            }
        } else {
            logger.error("createCxws cxws is null error.");
        }
    }


}
